#ifndef KCENTER_H_
#define KCENTER_H_
/*
 * kcenter.h
 *
 *  Created on: Mar 31, 2013
 *      Author: drewlewis
 */

#include <Eigen/Dense>
#include <Eigen/StdVector>

class KCenter{ // Will hold all the atoms that go in a specific trange

private:
  typedef  Eigen::aligned_allocator<Vector3> EigenStd;
  typedef  std::pair<int, Vector3> pair_int;



public:
  KCenter(const Vector3 &vec) :
    center_(vec){};

  KCenter& operator=(const KCenter &rhs){
      center_ = rhs.center_;
      return *this;
  }

  // adds an atom to our kcenter
  void add_neighbor(int charge, Vector3 vec){
    neighbors_.push_back(std::make_pair(charge, vec) );
  }

  // Return the position of the kcenter
  Vector3 center(){ return center_; }

  // Find distance from any vect to kcenter
  double distance(Vector3 &vec){
    return (vec - center_).norm();
  }

  // Compute the center position of the neighbors like center of mass without weights.
  Vector3 centroid(){

    size_t n_neighbors = neighbors_.size();
    Vector3 data_center(0,0,0);

    // coordinates of new center
    double x = 0;
    double y = 0;
    double z = 0;

    // Compute xyz
    for(std::size_t i = 0; i < n_neighbors; ++i){
      x += neighbors_[i].second[0];
      y += neighbors_[i].second[1];
      z += neighbors_[i].second[2];
    }

    //Get avearges
    x = x/n_neighbors;
    y = y/n_neighbors;
    z = z/n_neighbors;

    //Assign new pos
    data_center[0] = x;
    data_center[1] = y;
    data_center[2] = z;

    return data_center;
  }

  //Get rid of old data in kcenter
  void remove_data(){
    center_.fill(0.0);
    neighbors_.resize(0);
  }

  // Print location of all atoms in kcenter
  void print_neighbors(){
    for(std::size_t i = 0; i < neighbors_.size(); ++i){
      std::cout << neighbors_[i].second << std::endl;
    }
  }

  // Return number of atoms in kcenter
  size_t n_neighbors(){
    return neighbors_.size();
  }

  // prints the center of the kcenter
  void print_center(){
    std::cout << center_ << std::endl;
  }

  // gets the nuclear charge of neighbor i
  int neighbor_charge(int ineighbor){
    return neighbors_[ineighbor].first;
  }

  // Gets postion of neighbor i
  double neighbor_pos(int ineighbor, int xyz){
    // x = 0, y = 1, z = 2
    return neighbors_[ineighbor].second[xyz];
  }

private:
  // center of kcenter
  Vector3 center_;

  // atoms in kcenter
  std::vector< pair_int > neighbors_;

}; // Class KCenter





#endif /* KCENTER_H_ */
